// Copyright (c) 2008 Davy Brion (ralinx@davybrion.com)
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// 
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//       this list of conditions and the following disclaimer in the documentation
//       and/or other materials provided with the distribution.
//     * Neither the name of Davy Brion nor the names of the
//       contributors may be used to endorse or promote products derived from this
//       software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

using System.Collections.Generic;
using NHibernate.Criterion;

namespace NHibernate.Servicelayer.NHibernate
{
    public interface IRepository<T>
    {
        /// <summary>
        /// Retrieves the entity with the given id
        /// </summary>
        /// <param name="id"></param>
        /// <returns>the entity or null if it doesn't exist</returns>
        T Get(object id);

        /// <summary>
        /// Deletes the given entity
        /// </summary>
        /// <param name="entity"></param>
        void Delete(T entity);

        /// <summary>
        /// Deletes every entity that matches the given criteria
        /// </summary>
        /// <param name="criteria"></param>
        void Delete(DetachedCriteria criteria);

        /// <summary>
        /// Saves or updates the given entity
        /// </summary>
        /// <param name="entity"></param>
        void SaveOrUpdate(T entity);

        /// <summary>
        /// Returns each entity
        /// </summary>
        /// <returns></returns>
        IEnumerable<T> FindAll();

        /// <summary>
        /// Returns each entity that matches the given criteria
        /// </summary>
        /// <param name="criteria"></param>
        /// <returns></returns>
        IEnumerable<T> FindAll(DetachedCriteria criteria);

        /// <summary>
        /// Returns each entity that maches the given criteria, and orders the results 
        /// according to the given Orders
        /// </summary>
        /// <param name="criteria"></param>
        /// <param name="orders"></param>
        /// <returns></returns>
        IEnumerable<T> FindAll(DetachedCriteria criteria, params Order[] orders);

        /// <summary>
        /// Returns each entity that matches the given criteria, with support for paging, 
        /// and orders the results according to the given Orders
        /// </summary>
        /// <param name="criteria"></param>
        /// <param name="firstResult"></param>
        /// <param name="numberOfResults"></param>
        /// <param name="orders"></param>
        /// <returns></returns>
        IEnumerable<T> FindAll(DetachedCriteria criteria, int firstResult, int numberOfResults, params Order[] orders);

        /// <summary>
        /// Returns the one entity that matches the given criteria. Throws an exception if 
        /// more than one entity matches the criteria
        /// </summary>
        /// <param name="criteria"></param>
        /// <returns></returns>
        T FindOne(DetachedCriteria criteria);

        /// <summary>
        /// Returns the first entity to match the given criteria
        /// </summary>
        /// <param name="criteria"></param>
        /// <returns></returns>
        T FindFirst(DetachedCriteria criteria);

        /// <summary>
        /// Returns the first entity to match the given criteria, ordered by the given order
        /// </summary>
        /// <param name="criteria"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        T FindFirst(DetachedCriteria criteria, Order order);

        /// <summary>
        /// Returns true if at least one entity exists that matches the given criteria
        /// </summary>
        /// <param name="criteria"></param>
        /// <returns></returns>
        bool Exists(DetachedCriteria criteria);

        /// <summary>
        /// Returns the total number of entities that match the given criteria
        /// </summary>
        /// <param name="criteria"></param>
        /// <returns></returns>
        long Count(DetachedCriteria criteria);

        /// <summary>
        /// Returns the detached Criteria to return all the entities of this repository
        /// </summary>
        /// <returns></returns>
        DetachedCriteria CriteriaForAll();
    }
}